/**
 * pftransloader object
 */
var pftransloader = {
  prefs: null,
  strings: null,
  historyList: [],
  pfScope: {},
  imageUrl: null,
  
  /**
  * Loads the resources needed by the addon
  */
  onLoad: function() {
    // initialization code
    Components.utils.import("resource://gre/modules/Services.jsm", this.pfScope); // Import Services.jsm module
    this.initialized = true;
    this.strings = document.getElementById("pftransloader-strings");
    this.prefs = this.pfScope.Services.prefs.getBranch("extensions.pftransloader.");
    this.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
    this.prefs.addObserver("", this, false);
  },

  /**
  * Unloads the resources needed by the addon
  */  
  onUnload: function() {
    this.prefs.removeObserver("", this);
  },

  /**
  * Transloads an image to PhyreFile
  */  
  onTransloadImage: function(e, format) {
    var url = this.imageUrl;
    
    var request = new XMLHttpRequest();
    request.open('GET', this.prefs.getCharPref("pfPhyreFileUrl") + escape(url), true);
    request.onerror=function() { pftransloader.displayError(pftransloader.strings.getString("transloadFail")); }
    request.onreadystatechange = function(evt) {
      if (request.readyState == 4) {
        if(request.status == 200) {
          try {
            var jsonResponse = JSON.parse(request.responseText);
            if (typeof jsonResponse.error != 'undefined') {
              // invalid filetype error happens if the image doesn't have a proper filetype identifier
              if(jsonResponse.error == "ERROR: Invalid filetype.")
              {
                // add an arbitary image filetype to image url and try again
                pftransloader.setImageUrl(url + ".jpg");
                pftransloader.onTransloadImage(e, format);
                return;
              }
              pftransloader.displayError(jsonResponse.error);
            }          
            else {
              pftransloader.copyToClipboard(pftransloader.formatLink(jsonResponse, format));          
              pftransloader.displaySuccess(jsonResponse.name);
              pftransloader.historyList.push(jsonResponse);
              pftransloader.updateHistoryMenus();
            }
          }
          catch (e) {
            pftransloader.displayError(e);
          }
        }
        else {
          pftransloader.displayError(pftransloader.strings.getString("serverResponseError") + ": " + request.status);
        }
      }
    }
    
    request.send(null);
  },

  /**
  * Copies text to clipboard
  * @param copytext String to be copied to the clipboard
  * @returns True on success, false on error
  */   
  copyToClipboard: function(copytext) {
    try {
      var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
		  if (!str) return false;
        str.data = copytext;

		    var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
		    if (!trans) return false;

		    trans.addDataFlavor("text/unicode");
		    trans.setTransferData("text/unicode",str,copytext.length * 2);

		    var clipid = Components.interfaces.nsIClipboard;
		    var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(clipid);
		    if (!clip) return false;

		    clip.setData(trans,null,clipid.kGlobalClipboard);
		    return true;
	    }
	    catch(e)
	    {
		    return false;
	    }
  },

  /**
  * Formats the link
  * @param jsonResponse JSON response from PhyreFile
  * @returns Formatted link
  */
  formatLink: function(jsonResponse, format) {
    var intLinkType;
    if (format != null) intLinkType = format;
    else intLinkType = this.prefs.getIntPref("pfLinkType");
    
    switch(intLinkType)
    {
      case 1: return "[url=" + jsonResponse.pageurl + "][img]" + jsonResponse.fileurl + "[/img][/url]"; // BBCode
        break;
      case 2: return "[url=" + jsonResponse.pageurl + "][img]" + jsonResponse.thumburl + "[/img][/url]";
        break; // BBCode with thumbnails
      case 3: return "<a href=\"" + jsonResponse.pageurl + "\" alt=\"Image Hosting by PhyreFile\"><img src=\"" + jsonResponse.fileurl + "\"></a>";
        break; // Website embed
      case 4: return jsonResponse.fileurl;
        break; // Direct link
      case 5: return jsonResponse.pageurl;
        break; // View page link
      default: break;
    }
    return;
  },

  /**
  * Display a popup notification
  * @param message The message to be displayed
  * @param notificationId The id for the notification
  * @param mainAction The main action for the notification
  */  
  displayNotification: function(message, notificationId, mainAction) {    
    // Create and display the notification
    PopupNotifications.show(gBrowser.selectedBrowser, notificationId, message, "pftransloader-notification-icon", mainAction, null);
    return;
  },

  /**
  * Displays an error message
  * @param errortext Error string
  */
  displayError: function(errortext) {
    // Display error, unless silentmode is larger than 1
    if (!(this.prefs.getIntPref("pfSilentMode") > 1)) {
      var message = pftransloader.strings.getString("transloadError") + ": " + errortext;
      var notificationId = "pftransloader-error";
      if (errortext == "Not Logged in.") {
        var mainAction = {
          label: pftransloader.strings.getString("clickToLogin"),
          accessKey: pftransloader.strings.getString("clickToLoginAccessKey"),
          callback: function() {
            openUILinkIn(pftransloader.prefs.getCharPref("pfPhyreFileLoginUrl"), "tab");
          }
        }
        pftransloader.displayNotification(message, notificationId, mainAction);
      }
      else {
        pftransloader.displayNotification(message, notificationId);
      }
    }
  },

  /**
  * Displays an success message
  * @param imagename Name of the image succesfully transloaded
  */  
  displaySuccess: function(imagename) {
    // Display success, unless silentmode is larger than 0
    if (!(this.prefs.getIntPref("pfSilentMode") > 0)) {
      var message = pftransloader.strings.getFormattedString("linkCopied", [imagename]);
      var notificationId = "pftransloader-success";
      pftransloader.displayNotification(message, notificationId);
    }
  },

  /**
  * Clear history lists
  */  
  onClearHistory: function() {
    this.historyList = [];
    pftransloader.updateHistoryMenus();
  },

  /**
  * Update history list menu
  * @param menu String of the menu
  */  
  updateHistoryMenu: function(menu) {
	// get the separator and the history menu
	var separatorElement = document.getElementById('pftransloader_historySeparator' + menu);
    var historyListMenu = document.getElementById('pftransloader_historyMenu' + menu);
	
	// get current items in the history menu
	var currentHistoryItems = historyListMenu.getElementsByClassName("pftransloader_historyitem");
	// remove history items in reverse order to avoid problems with changing indexes
	for (var i = currentHistoryItems.length - 1; i >= 0 ; i--) {
	  separatorElement.parentNode.removeChild(currentHistoryItems[i]);
	}
	
	// if no history items in the list, add "empty" item in the menu
    if (this.historyList.length <= 0) {
	  var emptyListElement = document.createElement("menuitem");
	  emptyListElement.className = "pftransloader_historyitem";
	  emptyListElement.setAttribute("label", pftransloader.strings.getString("historyListEmpty"));
      var emptylist = separatorElement.parentNode.insertBefore(emptyListElement, separatorElement);
      emptylist.disabled = true;
    }
	// add items to history menu
	else if (this.historyList.length > 0) {
	  for (var i = 0; i < this.historyList.length; i++) {
	    var newHistoryItemElement = document.createElement("menuitem");
	    if (this.prefs.getBoolPref("pfPreviewIconsEnabled")) { // If previews enabled add preview images
		  newHistoryItemElement.className = "pftransloader_historyitem menuitem-iconic pftransloader_previewicon";
		  newHistoryItemElement.setAttribute('image', this.historyList[i].thumburl);
		}
		else {
		  newHistoryItemElement.className = "pftransloader_historyitem";
		}
	    newHistoryItemElement.setAttribute("label", this.historyList[i].name);
		var historyItem = separatorElement.parentNode.insertBefore(newHistoryItemElement, separatorElement);
		// add eventlistener to added historyitem
		historyItem.value = i;
		historyItem.listener = function() { pftransloader.onHistoryClick(this); };
        historyItem.addEventListener('command', historyItem.listener, false);
	  }
	}
  },

  /**
  * Update both history list menus
  */  
  updateHistoryMenus: function() {
    var intMaxEntries = this.prefs.getIntPref("pfHistoryMaxEntries"); // Limit the amount of entries in the history list
    if (this.historyList.length > intMaxEntries)
    {
      this.historyList = this.historyList.slice(-intMaxEntries);
    }
    pftransloader.updateHistoryMenu('App');
    pftransloader.updateHistoryMenu('History');
  },

  /**
  * Handle user clicking a image on a history menu
  * @param obj The image object clicked
  */  
  onHistoryClick: function(obj) {
    var image = this.historyList[obj.value];
    pftransloader.copyToClipboard(pftransloader.formatLink(image));
    pftransloader.displaySuccess(image.name);
  },
  
  /**
  * Show all users images in PhyreFile
  */  
  onShowAll: function() {
    openUILinkIn(this.prefs.getCharPref("pfPhyreFileShowAllUrl"), "tab"); // Open PhyreFile website in a new tab
  },

  /**
  * Observe changes in preferences
  * @param subject Subject
  * @param topic Topic
  * @param data Data
  */  
  observe: function(subject, topic, data)
   {
     if (topic != "nsPref:changed")
     {
       return;
     }
 
     switch(data)
     {
       case "pfPreviewIconsEnabled":
         pftransloader.updateHistoryMenus();
         break;
     }
   },
   /**
   * Set image url
   * @param url Url of the image
   */
   setImageUrl: function(url)
   {
     this.imageUrl = url;
   }
};

window.addEventListener("load", function() {pftransloader.onLoad();}, false);
window.addEventListener("unload", function() {pftransloader.onUnload();}, false);
